home *** CD-ROM | disk | FTP | other *** search
-
- #ifdef MPW
- # pragma segment TCL_2
- #endif
-
- /*********************************************************************
- File : stat.c - Macintosh implementation of stat()
- Author : Matthias Neeracher
- Started : 28May91 Language : MPW C
- 28May91 MN Created
- 28May91 MN isatty()
- Last : 28May91
-
- Copyright (c) 1991, Matthias Neeracher
- Copyright (c) 1993, Tim Endres - modifications
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
- *********************************************************************/
-
- #include <string.h>
- #include "ioctl.h"
- #include <errno.h>
- #include <Errors.h>
- #include <Files.h>
-
- #include "tcl.h"
- #include "tclUnix.h"
-
- /* As the field names of a CInfoParamBlockRec are spelled inconsistently,
- we have to use manual casts.
- */
-
- #define FILEINFO(cb) (*(HFileInfo *) (cb))
- #define DIRINFO(cb) (*(DirInfo *) (cb))
-
- OSErr
- GetCatInfo(char * path, CInfoPBPtr cb)
- {
- char * nextPath;
- char * tryPath;
- OSErr err;
- Str255 name;
-
- DIRINFO(cb).ioNamePtr = name;
- DIRINFO(cb).ioDrDirID = 0;
- DIRINFO(cb).ioVRefNum = 0;
- DIRINFO(cb).ioFDirIndex = 0;
-
- /* handle very long pathnames */
-
- while (strlen(path) > 255)
- {
- for (nextPath = path; tryPath = strchr(nextPath, ':'); nextPath = tryPath)
- if (tryPath-nextPath > 31)
- return bdNamErr;
- else if (tryPath-path > 255)
- break;
-
- if (nextPath == path && !tryPath)
- return bdNamErr;
-
- name[0] = nextPath-path;
- strncpy((char *) name+1, path, name[0]);
-
- err = PBGetCatInfo(cb, false);
- if (err != noErr)
- return err;
-
- if (! (DIRINFO(cb).ioFlAttrib & 0x10))
- {
- return bdNamErr;
- }
-
- DIRINFO(cb).ioFDirIndex = 0;
-
- path = nextPath+1;
- }
-
- name[0] = strlen(path);
- strncpy((char *) name+1, path, name[0]);
-
- err = PBGetCatInfo(cb, false);
-
- return err;
- }
-
- OSErr GetFDCatInfo(int fd, CInfoPBPtr cb)
- {
- short fRef;
- OSErr err;
- FCBPBRec fcb;
- Str255 fname;
-
- if (ioctl(fd, FIOREFNUM, (long *) &fRef) == -1)
- return fnfErr;
-
- fcb.ioNamePtr = fname;
- fcb.ioRefNum = fRef;
- fcb.ioFCBIndx = 0;
- err = PBGetFCBInfo(&fcb, false);
- if (err != noErr)
- return err;
-
- FILEINFO(cb).ioNamePtr = fname;
- FILEINFO(cb).ioDirID = fcb.ioFCBParID;
- FILEINFO(cb).ioVRefNum = fcb.ioFCBVRefNum;
- FILEINFO(cb).ioFDirIndex = 0;
-
- return PBGetCatInfo(cb, false);
- }
-
- OSErr GetVolume(char * path, ParmBlkPtr pb)
- {
- char * volEnd;
- OSErr err;
- WDPBRec wd;
- Str255 name;
-
- volEnd = strchr(path, ':');
-
- pb->volumeParam.ioNamePtr = name;
-
- if (path[0] == ':' || ! volEnd)
- {
- err = PBGetVol(pb, false);
- if (err != noErr)
- return err;
-
- wd.ioNamePtr = name;
- wd.ioVRefNum = pb->volumeParam.ioVRefNum;
- wd.ioWDIndex = 0;
- err = PBGetWDInfo(&wd, false);
- if (err == noErr)
- pb->volumeParam.ioVRefNum = wd.ioWDVRefNum;
-
- pb->volumeParam.ioVolIndex = 0;
- }
- else
- {
- pb->volumeParam.ioVolIndex = -1;
-
- name[0] = (volEnd - path) + 1; /* include ':' */
- strncpy((char *) name+1, path, name[0]);
- }
-
- err = PBGetVInfo(pb, false);
-
- return err;
- }
-
- OSErr
- GetFDVolume(int fd, ParmBlkPtr pb)
- {
- OSErr err;
- short fRef;
- Str255 name;
- FCBPBRec fcb;
-
- if ( ioctl(fd, FIOREFNUM, (long *) &fRef) == -1 )
- return fnfErr;
-
- fcb.ioNamePtr = name;
- fcb.ioRefNum = fRef;
- fcb.ioFCBIndx = 0;
- if (err = PBGetFCBInfo(&fcb, false))
- return err;
-
- pb->volumeParam.ioNamePtr = name;
- pb->volumeParam.ioVRefNum = fcb.ioFCBVRefNum;
- pb->volumeParam.ioVolIndex = 0;
-
- return PBGetVInfo(pb, false);
- }
-
- int
- mac_do_stat(CInfoPBPtr cb, ParmBlkPtr pb, struct stat * buf)
- {
- buf->st_ino = FILEINFO(cb).ioDirID;
- buf->st_dev = pb->ioParam.ioVRefNum;
- buf->st_nlink = 1;
- buf->st_uid = 0;
- buf->st_gid = 0;
- buf->st_atime = FILEINFO(cb).ioFlMdDat;
- buf->st_mtime = FILEINFO(cb).ioFlMdDat;
- buf->st_ctime = FILEINFO(cb).ioFlCrDat;
- buf->st_blksize= pb->volumeParam.ioVAlBlkSiz;
-
- if (FILEINFO(cb).ioFlAttrib & 0x10)
- {
- /* DIRECTORY */
- buf->st_mode = S_IFDIR | 0777;
- buf->st_size = buf->st_blksize; /* Not known for directories */
- buf->st_rdev = 0; /* UNDONE - couldn't this be a "wdRefnum" if one exists? */
- buf->st_nlink = DIRINFO(cb).ioDrNmFls;
-
- buf->st_rsize = 0;
- buf->st_parid = DIRINFO(cb).ioDrParID;
-
- buf->fdType = (long)'Fldr';
- buf->fdCreator = (long)'Fldr';
- /* UNDONE - another time maybe...
- buf->finfo = FILEINFO(cb).ioFlFndrInfo;
- buf->fxinfo = FILEINFO(cb).ioFlXFndrInfo;
- */
- }
- else
- {
- /* FILE */
- buf->st_mode = S_IFREG | 0666;
- buf->st_size = FILEINFO(cb).ioFlLgLen;
- buf->st_rdev = FILEINFO(cb).ioFRefNum;
-
- if (FILEINFO(cb).ioFlAttrib & 0x01) /* not locked? */
- buf->st_mode &= 0222;
-
- if (FILEINFO(cb).ioFlFndrInfo.fdType == 'APPL')
- buf->st_mode |= 0111;
-
- buf->st_rsize = FILEINFO(cb).ioFlRLgLen;
- buf->st_parid = FILEINFO(cb).ioFlParID;
-
- buf->fdType = FILEINFO(cb).ioFlFndrInfo.fdType;
- buf->fdCreator = FILEINFO(cb).ioFlFndrInfo.fdCreator;
- /* UNDONE - another time maybe...
- buf->finfo = FILEINFO(cb).ioFlFndrInfo;
- buf->fxinfo = FILEINFO(cb).ioFlXFndrInfo;
- */
- }
-
- buf->st_blocks = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize;
-
- return 0;
- }
-
- int
- stat(char * path, struct stat * buf)
- {
- int result;
- CInfoPBRec cb;
- ParamBlockRec pb;
-
- if (GetCatInfo(path, &cb) || GetVolume(path, &pb))
- {
- errno = ENOENT;
- return -1;
- }
- else
- {
- result = mac_do_stat(&cb, &pb, buf);
- return result;
- }
- }
-
- int
- lstat(char * path, struct stat * buf)
- {
- return stat(path, buf);
- }
-
- int
- fstat(int fd, struct stat * buf)
- {
- int result;
- CInfoPBRec cb;
- ParamBlockRec pb;
-
- if (GetFDCatInfo(fd, &cb) || GetFDVolume(fd, &pb))
- {
- errno = ENOENT;
-
- return -1;
- }
- else
- {
- result = mac_do_stat(&cb, &pb, buf);
- if ( ! ioctl(fd, FIOINTERACTIVE, NULL) )
- {
- /* MPW window */
- buf->st_mode |= S_IFCHR;
- buf->st_atime = time(NULL);
- buf->st_mtime = time(NULL);
- buf->st_ctime = time(NULL);
- }
- return result;
- }
- }
-
- int
- access(const char *filename, int mode)
- {
- struct stat statbuf;
-
- if ( stat((char *)filename, &statbuf) < 0 )
- {
- return -1;
- }
-
- if ( S_ISDIR( statbuf.st_mode ) )
- {
- /* DIR */ /* R_OK, W_OK, X_OK, F_OK */
- if ( (mode & W_OK) != 0 )
- return -1;
-
- return 0;
- }
- else
- {
- /* FILE */
- if ( (mode & W_OK) != 0 ) /* UNDONE - use MacOS call for better results! */
- if (statbuf.st_rdev > 0) /* it is open... */
- return -1;
-
- if ( (mode & X_OK) != 0 ) /* UNDONE - use MacOS call for better results! */
- if (statbuf.fdType != (long)'APPL')
- return -1;
-
- return 0;
- }
-
- return 0;
- }
-
- #ifndef THINK_C
-
- int
- isatty(int fd)
- {
- return !ioctl(fd, FIOINTERACTIVE, NULL);
- }
-
- #endif
-
- #ifdef test
-
- #include <stdio.h>
-
- #define DUMP(EXPR, MODE) printf("%s = %"#MODE"\n", #EXPR, EXPR);
-
- int main(int argc, char ** argv)
- {
- int res;
- struct stat statbuf;
-
- printf("StdIn is %s TTY.\n", isatty(0)?"a":"no");
- printf("StdOut is %s TTY.\n", isatty(1)?"a":"no");
- printf("StdErr is %s TTY.\n\n", isatty(2)?"a":"no");
-
- if (argc == 1)
- res = fstat(0, &statbuf);
- else
- res = stat(argv[1], &statbuf);
-
- if (res)
- printf("Error occurred.\n");
- else {
- DUMP(statbuf.st_dev,d);
- DUMP(statbuf.st_ino,d);
- DUMP(statbuf.st_mode,#o);
- DUMP(statbuf.st_nlink,d);
- DUMP(statbuf.st_uid,d);
- DUMP(statbuf.st_gid,d);
- DUMP(statbuf.st_rdev,d);
- DUMP(statbuf.st_size,d);
- DUMP(statbuf.st_atime,u);
- DUMP(statbuf.st_mtime,u);
- DUMP(statbuf.st_ctime,u);
- DUMP(statbuf.st_blksize,d);
- DUMP(statbuf.st_blocks,d);
- }
- return 0;
- }
- #endif
-
- #ifdef NEVER_DEFINED
-
- cd {tclSrc}
- C -mbg full -d test {active}
- Link -t "MPST" -c "MPS " ∂
- -o teststat ∂
- {active}.o ∂
- {Libraries}RunTime.o ∂
- {Libraries}Interface.o ∂
- {CLibraries}StdCLib.o
- teststat ""
- StdIn is a TTY.
- StdOut is a TTY.
- StdErr is a TTY.
-
- statbuf.st_dev = -2
- statbuf.st_ino = 131324
- statbuf.st_mode = 040777
- statbuf.st_nlink = 45
- statbuf.st_uid = 0
- statbuf.st_gid = 0
- statbuf.st_rdev = 0
- statbuf.st_size = 3584
- statbuf.st_atime = 2834961968
- statbuf.st_mtime = 2834961968
- statbuf.st_ctime = 2834354745
- statbuf.st_blksize = 3584
- statbuf.st_blocks = 1
-
- pwd
- Moon:tcl7.0:
-
- teststat Moon:tcl7.0:src
- StdIn is a TTY.
- StdOut is a TTY.
- StdErr is a TTY.
-
- statbuf.st_dev = -5
- statbuf.st_ino = 4648
- statbuf.st_mode = 040777
- statbuf.st_nlink = 1
- statbuf.st_uid = 0
- statbuf.st_gid = 0
- statbuf.st_rdev = 0
- statbuf.st_size = 2048
- statbuf.st_atime = 2834835315
- statbuf.st_mtime = 2834835315
- statbuf.st_ctime = 2834354745
- statbuf.st_blksize = 2048
- statbuf.st_blocks = 1
-
-
- #endif
-
-